package com.huicheng.ui;

import java.text.Format;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.huicheng.R;
import com.huicheng.service.BluetoothLeService;
import com.huicheng.utils.HttpUtil;
import com.huicheng.utils.SharedPreUtils;

import org.json.JSONException;
import org.json.JSONObject;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

/**
 * 特别说明：HC_BLE助手是广州汇承信息科技有限公司独自研发的手机APP，方便用户调试08蓝牙模块。
 * 本软件只能支持安卓版本4.3并且有蓝牙4.0的手机使用。
 * 另外对于自家的05、06模块，要使用另外一套蓝牙2.0的手机APP，用户可以在汇承官方网的下载中心自行下载。
 * 本软件提供代码和注释，免费给购买汇承08模块的用户学习和研究，但不能用于商业开发，最终解析权在广州汇承信息科技有限公司。
 **/

/**
 * @author 广州汇承信息科技有限公司
 * @Description: TODO<Ble_Activity实现连接BLE,发送和接受BLE的数据>
 * @data: 2014-10-20 下午12:12:04
 * @version: V1.0
 */
public class Ble_Activity extends Activity implements OnClickListener {

    private final static String TAG = Ble_Activity.class.getSimpleName();
    //蓝牙4.0的UUID,其中0000ffe1-0000-1000-8000-00805f9b34fb是广州汇承信息科技有限公司08蓝牙模块的UUID
    public static String HEART_RATE_MEASUREMENT = "0000ffe1-0000-1000-8000-00805f9b34fb";
    public static String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
    public static String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
    public static String EXTRAS_DEVICE_RSSI = "RSSI";
    //蓝牙连接状态
    private boolean mConnected = false;
    private String status = "正在连接";
    //蓝牙名字
    private String mDeviceName;
    //蓝牙地址
    private String mDeviceAddress;
    //蓝牙信号值
    private String mRssi;
    private Bundle b;
    private String rev_str = "";
    //蓝牙service,负责后台的蓝牙服务
    private static BluetoothLeService mBluetoothLeService;
    //文本框，显示接受的内容
    private TextView rev_tv, connect_state;
    //发送按钮
    private Button send_btn;
    //文本编辑框
    private EditText send_et;
    private ScrollView rev_sv;

    private Button get_data_button;

    private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
    //蓝牙特征值
    private static BluetoothGattCharacteristic target_chara = null;
    private Handler mhandler = new Handler();

    private Button report_button;
    private Button saveData;
    private String press_show = null;
    private Handler myHandler = new Handler() {
        // 2.重写消息处理函数
        public void handleMessage(Message msg) {
            switch (msg.what) {
                // 判断发送的消息
                case 1:
                    // 更新View
                    String state = msg.getData().getString("connect_state");

                    if (TextUtils.equals(state, "connected")) {
                        connect_state.setText("连接成功");
                    } else {
                        connect_state.setText("连接失败");
                    }
                    break;
                case 2:
                    Toast.makeText(Ble_Activity.this, "上报成功", Toast.LENGTH_LONG).show();
                    break;
                case 3:
                    Toast.makeText(Ble_Activity.this, "上报失败", Toast.LENGTH_LONG).show();
                    break;

            }
            super.handleMessage(msg);
        }

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ble_activity);
        b = getIntent().getExtras();
        //从意图获取显示的蓝牙信息
        mDeviceName = b.getString(EXTRAS_DEVICE_NAME);
        mDeviceAddress = b.getString(EXTRAS_DEVICE_ADDRESS);
        mRssi = b.getString(EXTRAS_DEVICE_RSSI);

		/* 启动蓝牙service */
        Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
        bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
        init();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解除广播接收器
        unregisterReceiver(mGattUpdateReceiver);
        unbindService(mServiceConnection);
        mBluetoothLeService = null;
    }


    @Override
    public void onBackPressed() {
        super.onBackPressed();
//        SharedPreUtils.getInstance().removeString("userName");
        SharedPreUtils.getInstance().removeString("userName");
        SharedPreUtils.getInstance().removeString("userPhone");
        SharedPreUtils.getInstance().removeString("serverCode");
        finish();
    }

    // Activity出来时候，绑定广播接收器，监听蓝牙连接服务传过来的事件
    @Override
    protected void onResume() {
        super.onResume();
        //绑定广播接收器
        registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
        if (mBluetoothLeService != null) {
            //根据蓝牙地址，建立连接
            final boolean result = mBluetoothLeService.connect(mDeviceAddress);
            Log.d(TAG, "Connect request result=" + result);
        }
    }

    /**
     * @return void
     * @throws
     * @Title: init
     * @Description: TODO(初始化UI控件)
     */
    private void init() {
        rev_sv = (ScrollView) this.findViewById(R.id.rev_sv);
        rev_tv = (TextView) this.findViewById(R.id.rev_tv);
        connect_state = (TextView) this.findViewById(R.id.connect_state);
        send_btn = (Button) this.findViewById(R.id.send_btn);
        send_et = (EditText) this.findViewById(R.id.send_et);
        connect_state.setText(status);
        send_btn.setOnClickListener(this);

        report_button = (Button) findViewById(R.id.report_data);
        report_button.setOnClickListener(this);

        get_data_button = (Button) findViewById(R.id.get_data_button);
        get_data_button.setOnClickListener(this);

        saveData = (Button) findViewById(R.id.saveData);
        saveData.setOnClickListener(this);
        press_show = this.getResources().getString(R.string.press_show);
    }

    /* BluetoothLeService绑定的回调函数 */
    private final ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName,
                                       IBinder service) {
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service)
                    .getService();
            if (!mBluetoothLeService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");
                finish();
            }
            // Automatically connects to the device upon successful start-up
            // initialization.
            // 根据蓝牙地址，连接设备
            mBluetoothLeService.connect(mDeviceAddress);

        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mBluetoothLeService = null;
        }

    };

    /**
     * 广播接收器，负责接收BluetoothLeService类发送的数据
     */
    private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action))//Gatt连接成功
            {
                mConnected = true;
                status = "connected";
                //更新连接状态
                updateConnectionState(status);
                System.out.println("BroadcastReceiver :" + "device connected");

            } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action))//Gatt连接失败
            {
                mConnected = false;
                status = "disconnected";
                //更新连接状态
                updateConnectionState(status);
                System.out.println("BroadcastReceiver :"
                        + "device disconnected");

            } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action))//发现GATT服务器
            {
                // Show all the supported services and characteristics on the
                // user interface.
                //获取设备的所有蓝牙服务
                displayGattServices(mBluetoothLeService.getSupportedGattServices());
                System.out.println("BroadcastReceiver :" + "device SERVICES_DISCOVERED");
            } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action))//有效数据
            {
                //处理发送过来的数据
                displayData(intent.getExtras().getString(BluetoothLeService.EXTRA_DATA));
                System.out.println("BroadcastReceiver onData:" + intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
            }
        }
    };

    /* 更新连接状态 */
    private void updateConnectionState(String status) {
        Message msg = new Message();
        msg.what = 1;
        Bundle b = new Bundle();
        b.putString("connect_state", status);
        msg.setData(b);
        //将连接状态更新的UI的textview上
        myHandler.sendMessage(msg);
        System.out.println("connect_state:" + status);

    }

    /* 意图过滤器 */
    private static IntentFilter makeGattUpdateIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        return intentFilter;
    }

    /**
     * @param @param rev_string(接受的数据)
     * @return void
     * @throws
     * @Title: displayData
     * @Description: TODO(接收到的数据在scrollview上显示)
     */
    private void displayData(final String rev_string) {

//		if (rev_string.startsWith("press") || rev_string.startsWith("startpress") ||rev_string.startsWith("Averg")){
//			runOnUiThread(new Runnable() {
//				@Override
//				public void run() {
//					String tempNum = rev_string.substring(rev_string.indexOf(":")+1,rev_string.indexOf(";"));
//					String press = rev_string.substring(rev_string.indexOf(";")+1,rev_string.length());
//					String result = String.format(press_show,tempNum,press);
//
//					rev_tv.setText(rev_tv.getText()+"\n"+result);
//					rev_sv.scrollTo(0,rev_tv.getMeasuredHeight());
//				}
//			});
//			rev_strLists.add(rev_string);
//		}
//		if (rev_string.startsWith("press") || rev_string.startsWith("startpress") ||rev_string.startsWith("Averg")){

//		String tempNum = rev_string.substring(rev_string.indexOf(":")+1,rev_string.indexOf(";"));
//		String press = rev_string.substring(rev_string.indexOf(";")+1,rev_string.length());
//		String result = String.format(press_show,tempNum,press);

//		rev_str +=result;

        rev_str += rev_string;

        datas = rev_str.split("\n");
        String tempDa = datas[datas.length - 1];
        if (tempDa != null && tempDa.contains("Averg") && tempDa.contains(";") && tempDa.contains(":")) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < datas.length; i++) {
                        String temp = datas[i];
                        if (temp.contains("start")) {
                            temp = temp.replace("start", "");
                        }
                        if (i == datas.length - 1) {
                            rev_tv.setText(rev_tv.getText().toString().trim() + "\n" + temp.replace("Averg", "编号").replace(";", ",平均值:") + "\n\n");
                        } else {
                            if (i == 0) {
                                temp.substring(temp.indexOf("p") + 1, temp.length());
                            }
                            rev_tv.setText(rev_tv.getText().toString().trim() + "\n" + temp.replace("press", "编号").replace(";", ",压力值:"));
                        }
                        rev_strLists.add(temp);
                        rev_sv.scrollTo(0, rev_tv.getMeasuredHeight());
                        System.out.println("rev:" + datas[i]);
                    }
                    Toast.makeText(Ble_Activity.this, "获取成功", Toast.LENGTH_LONG).show();

                }
            });
        }
    }

    private String[] datas = new String[]{};
    private ArrayList<String> rev_strLists = new ArrayList<String>();


    private void reportData(final String data) {
        Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext(data);
                e.onComplete();
            }
        }).subscribeOn(Schedulers.single()).map(new Function<String, String>() {
            @Override
            public String apply(String s) throws Exception {
//                String responseStr = HttpUtil.httpPost("http://fl.xassp.com:8089/MYBase/GetAPPMessage.action?appmsg=" + s, "test");
//                String responseStr = HttpUtil.httpPost("http://192.168.0.130:8080/MYBase/GetAPPMessage.action?appmsg=" + s, "test");
                String responseStr = HttpUtil.httpPost("http://service.shruihe.com/Rhser/receive?appmsg=" + s, "test");

                if (responseStr == null) {
                    return "404";
                }
                return responseStr;
            }
        }).subscribeOn(AndroidSchedulers.mainThread()).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Message message = myHandler.obtainMessage();

                if (TextUtils.equals(s, "200")) {
                    message.what = 2;
                    if (rev_strLists != null && rev_strLists.size() > 0) {
                        rev_strLists.clear();
                    }
                } else {
                    message.what = 3;
                }
                myHandler.sendMessage(message);
            }
        });
    }

    /**
     * @return void
     * @throws
     * @Title: displayGattServices
     * @Description: TODO(处理蓝牙服务)
     */
    private void displayGattServices(List<BluetoothGattService> gattServices) {

        if (gattServices == null)
            return;
        String uuid = null;
        String unknownServiceString = "unknown_service";
        String unknownCharaString = "unknown_characteristic";

        // 服务数据,可扩展下拉列表的第一级数据
        ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();

        // 特征数据（隶属于某一级服务下面的特征值集合）
        ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>();

        // 部分层次，所有特征值集合
        mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

        // Loops through available GATT Services.
        for (BluetoothGattService gattService : gattServices) {

            // 获取服务列表
            HashMap<String, String> currentServiceData = new HashMap<String, String>();
            uuid = gattService.getUuid().toString();

            // 查表，根据该uuid获取对应的服务名称。SampleGattAttributes这个表需要自定义。

            gattServiceData.add(currentServiceData);

            System.out.println("Service uuid:" + uuid);

            ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>();

            // 从当前循环所指向的服务中读取特征值列表
            List<BluetoothGattCharacteristic> gattCharacteristics = gattService
                    .getCharacteristics();

            ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();

            // Loops through available Characteristics.
            // 对于当前循环所指向的服务中的每一个特征值
            for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                charas.add(gattCharacteristic);
                HashMap<String, String> currentCharaData = new HashMap<String, String>();
                uuid = gattCharacteristic.getUuid().toString();

                if (gattCharacteristic.getUuid().toString()
                        .equals(HEART_RATE_MEASUREMENT)) {
                    // 测试读取当前Characteristic数据，会触发mOnDataAvailable.onCharacteristicRead()
                    mhandler.postDelayed(new Runnable() {

                        @Override
                        public void run() {
                            // TODO Auto-generated method stub
                            mBluetoothLeService
                                    .readCharacteristic(gattCharacteristic);
                        }
                    }, 200);

                    // 接受Characteristic被写的通知,收到蓝牙模块的数据后会触发mOnDataAvailable.onCharacteristicWrite()
                    mBluetoothLeService.setCharacteristicNotification(
                            gattCharacteristic, true);
                    target_chara = gattCharacteristic;
                    // 设置数据内容
                    // 往蓝牙模块写入数据
                    // mBluetoothLeService.writeCharacteristic(gattCharacteristic);
                }
                List<BluetoothGattDescriptor> descriptors = gattCharacteristic
                        .getDescriptors();
                for (BluetoothGattDescriptor descriptor : descriptors) {
                    System.out.println("---descriptor UUID:" + descriptor.getUuid());
                    // 获取特征值的描述
                    mBluetoothLeService.getCharacteristicDescriptor(descriptor);
                    // mBluetoothLeService.setCharacteristicNotification(gattCharacteristic,
                    // true);
                }

                gattCharacteristicGroupData.add(currentCharaData);
            }
            // 按先后顺序，分层次放入特征值集合中，只有特征值
            mGattCharacteristics.add(charas);
            // 构件第二级扩展列表（服务下面的特征值）
            gattCharacteristicData.add(gattCharacteristicGroupData);

        }

    }

    /*
     * 发送按键的响应事件，主要发送文本框的数据
     */
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        int id = v.getId();
        if (id == R.id.report_data) {
//			Log.d("lk","[Ble_Activity] onclick rev_lists:"+rev_strLists.toString());
//			if (rev_strLists!=null&&rev_strLists.size()>0){
//				reportData(rev_strLists.toString());
//			}
            showUserInfoDialog();
        }
        if (id == R.id.saveData) {
//			target_chara.setValue(send_et.getText().toString());
//			//调用蓝牙服务的写特征值方法实现发送数据
//			mBluetoothLeService.writeCharacteristic(target_chara);
//			Log.d("lk","[Ble_Activity] onclick rev_lists:"+rev_tv.getText().toString().trim());

        }
        if (id == R.id.get_data_button) {
            rev_str = "";
            rev_tv.setText("");
            if (rev_strLists != null && rev_strLists.size() > 0) {
                rev_strLists.clear();
            }
            if (target_chara != null) {
                target_chara.setValue("start");
                //调用蓝牙服务的写特征值方法实现发送数据
                mBluetoothLeService.writeCharacteristic(target_chara);
            }

        }
    }


    private void showUserInfoDialog() {
        Log.d("lk", "[Ble_Activity] showUserInfoDialog");
        AlertDialog.Builder dialog = new AlertDialog.Builder(this);
//        dialog.setTitle("数据上报信息");
        LayoutInflater layoutInflater = LayoutInflater.from(this);
        View userView = layoutInflater.inflate(R.layout.user_info_layout, null);
        dialog.setView(userView);

        final EditText server_code_edit = (EditText) userView.findViewById(R.id.server_code_edit);
        final EditText user_name_edit = (EditText) userView.findViewById(R.id.user_name_edit);
        final EditText user_phone_edit = (EditText) userView.findViewById(R.id.user_phone_edit);
        final EditText user_address_edit = (EditText) userView.findViewById(R.id.user_address_edit);

        String server_code = SharedPreUtils.getInstance().getString("serverCode");
        String userName = SharedPreUtils.getInstance().getString("userName");
        String userPhone = SharedPreUtils.getInstance().getString("userPhone");
        String userAddress = SharedPreUtils.getInstance().getString("userAddress");

        if (!TextUtils.isEmpty(server_code)) {
            server_code_edit.setText(server_code);
        }
        if (!TextUtils.isEmpty(userName)) {
            user_name_edit.setText(userName);
        }
        if (!TextUtils.isEmpty(userPhone)) {
            user_phone_edit.setText(userPhone);
        }
        if (!TextUtils.isEmpty(userAddress)) {
            user_address_edit.setText(userAddress);
        }

        dialog.setPositiveButton("确定上报", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                String server_code = server_code_edit.getText().toString().trim();
                String userName = user_name_edit.getText().toString().trim();
                String userPhone = user_phone_edit.getText().toString().trim();
                String userAddress = user_address_edit.getText().toString().trim();
                if (TextUtils.isEmpty(server_code)) {
                    Toast.makeText(Ble_Activity.this, "服务编码不能为空", Toast.LENGTH_LONG).show();
                    return;
                }
                if (TextUtils.isEmpty(userName)) {
                    Toast.makeText(Ble_Activity.this, "业主姓名不能为空", Toast.LENGTH_LONG).show();
                    return;
                }
                if (TextUtils.isEmpty(userPhone)) {
                    Toast.makeText(Ble_Activity.this, "业主手机号不能为空", Toast.LENGTH_LONG).show();
                    return;
                }
                if (TextUtils.isEmpty(userAddress)) {
                    Toast.makeText(Ble_Activity.this, "业主地址不能为空", Toast.LENGTH_LONG).show();
                    return;
                }
                SharedPreUtils.getInstance().putSting("serverCode", server_code);
                SharedPreUtils.getInstance().putSting("userName", userName);
                SharedPreUtils.getInstance().putSting("userPhone", userPhone);
                SharedPreUtils.getInstance().putSting("userAddress", userAddress);

                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("servid", server_code);
                    jsonObject.put("name", SharedPreUtils.getInstance().getString("name"));
                    jsonObject.put("tel", SharedPreUtils.getInstance().getString("phone"));
                    jsonObject.put("custname", userName);
                    jsonObject.put("custtel", userPhone);
                    jsonObject.put("custaddr", userAddress);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                Log.d("lk", "[Ble_Activity] onclick rev_lists:" + rev_strLists.toString() + "  userJson:" + jsonObject.toString());
                if (rev_strLists != null && rev_strLists.size() > 0) {
//                    reportData(rev_strLists.toString());
                    reportData(rev_strLists.toString()+"@"+jsonObject.toString());
                }
//                String test = "[startpress:00245;0.000Mpa, press:00245;0.000Mpa, press:00245;0.000Mpa, press:00245;0.000Mpa, press:00245;0.000Mpa, press:00245;0.000Mpa, Averg:00245;0.000Mpa]";
//                reportData(test+"@"+jsonObject.toString());
                dialogInterface.dismiss();
            }
        });
        dialog.setNeutralButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();
            }
        });
        dialog.show();
    }


}
